package com.zsr.example.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zsr.example.config.exception.CommonJsonException;
import com.zsr.example.entity.EduCourse;
import com.zsr.example.entity.EduCourseDescription;
import com.zsr.example.entity.EduSection;
import com.zsr.example.entity.EduTeacher;
import com.zsr.example.mapper.EduCourseMapper;
import com.zsr.example.service.*;
import com.zsr.example.util.JwtUtil;
import com.zsr.example.util.constants.BusinessEnum;
import com.zsr.example.util.constants.CourseConstants;
import com.zsr.example.util.constants.ErrorEnum;
import com.zsr.example.vo.ChapterVo;
import com.zsr.example.vo.CourseInfoVo;
import com.zsr.example.vo.CoursePublishVo;
import com.zsr.example.vo.CourseReq;
import com.zsr.example.vo.front.CourseFrontInfoVo;
import com.zsr.example.vo.front.CourseFrontReq;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * <p>
 * 课程 服务实现类
 * </p>
 *
 * @author zsr
 * @since 2021-11-15
 */
@Service
public class EduCourseServiceImpl extends ServiceImpl<EduCourseMapper, EduCourse> implements EduCourseService {

    //课程描述
    @Autowired
    private EduCourseDescriptionService eduCourseDescriptionService;

    @Autowired
    private EduSectionService eduSectionService;

    @Autowired
    private EduChapterService eduChapterService;

    @Autowired
    private TOrderService orderService;

    @Autowired
    private EduTeacherService teacherService;

    @Autowired
    private EduCollectService collectService;

    /**
     * 添加课程基本信息的方法
     *
     * @param courseInfoVo
     * @return 返回添加实体的id
     */
    @Override
    public String saveCourseInfo(CourseInfoVo courseInfoVo) {
        EduCourse eduCourse = new EduCourse();
        BeanUtils.copyProperties(courseInfoVo, eduCourse);//复制属性
        boolean save = this.save(eduCourse);

        if (!save) throw new CommonJsonException(ErrorEnum.E_20001);

        //课程描述
        EduCourseDescription eduCourseDescription = new EduCourseDescription()
                .setId(eduCourse.getId())
                .setDescription(courseInfoVo.getDescription());
        boolean save1 = eduCourseDescriptionService.save(eduCourseDescription);
        if (!save1) throw new CommonJsonException(ErrorEnum.E_20001);

        return eduCourse.getId();
    }

    /**
     * 根据课程id获取信息
     *
     * @param courseId
     * @return
     */
    @Override
    public CourseInfoVo getCourseInfoById(String courseId) {
        //1 查询课程表
        EduCourse eduCourse = this.getById(courseId);
        if (eduCourse == null) throw new CommonJsonException(ErrorEnum.E_90004);

        CourseInfoVo courseInfoVo = new CourseInfoVo();
        BeanUtils.copyProperties(eduCourse, courseInfoVo);

        //2 查询描述表
        EduCourseDescription description = eduCourseDescriptionService.getById(courseId);
        if (description != null) courseInfoVo.setDescription(description.getDescription());

        return courseInfoVo;
    }

    @Override
    public void updateCourseInfoById(CourseInfoVo courseInfoVo) {
        //保存课程基本信息
        EduCourse eduCourse = new EduCourse();
        BeanUtils.copyProperties(courseInfoVo, eduCourse);
        boolean resultCourse = this.updateById(eduCourse);
        if (!resultCourse) throw new CommonJsonException(ErrorEnum.E_20001);

        //保存课程详情信息
        EduCourseDescription courseDescription = new EduCourseDescription()
                .setDescription(courseInfoVo.getDescription())
                .setId(eduCourse.getId());
        boolean resultDescription = eduCourseDescriptionService.saveOrUpdate(courseDescription);
        if (!resultDescription) throw new CommonJsonException(ErrorEnum.E_20001);

    }

    @Override
    public CoursePublishVo getCoursePublishVoById(String id) {
        CoursePublishVo coursePublishVo = baseMapper.selectCoursePublishVoById(id);
        return coursePublishVo;
    }

    @Override
    public boolean publishCourseById(String id) {
        EduCourse course = new EduCourse();
        course.setId(id);
        course.setStatus(EduCourse.COURSE_NORMAL);
        int count = baseMapper.updateById(course);
        return count > 0;
    }

    @Override
    public void pageQuery(Page<EduCourse> pageParam, CourseReq courseReq) {
        QueryWrapper<EduCourse> queryWrapper = new QueryWrapper<>();
        queryWrapper.orderByDesc("gmt_create");

        //如果条件为空 返回全部
        if (courseReq == null) {
            baseMapper.selectPage(pageParam, queryWrapper);
            return;
        }

        String title = courseReq.getTitle();
        String teacherId = courseReq.getTeacherId();
        String subjectParentId = courseReq.getSubjectParentId();
        String subjectId = courseReq.getSubjectId();
        String status = courseReq.getStatus();

        if (!StringUtils.isEmpty(title)) queryWrapper.like("title", title);

        if (!StringUtils.isEmpty(teacherId)) queryWrapper.eq("teacher_id", teacherId);

        if (!StringUtils.isEmpty(subjectParentId))
            queryWrapper.eq("subject_parent_id", subjectParentId);

        if (!StringUtils.isEmpty(subjectId)) queryWrapper.eq("subject_id", subjectId);

        if (!StringUtils.isEmpty(status)) queryWrapper.eq("status", status);


        baseMapper.selectPage(pageParam, queryWrapper);
    }

    @Override
    @Transactional
    public boolean removeCourseById(String courseId) {
        //1.根据课程id删除小节
        eduSectionService.removeVideoByCourseId(courseId);

        //2.根据课程id删除章节
        eduChapterService.removeChapterByCourseId(courseId);

        //3.根据课程id删除描述
        eduCourseDescriptionService.removeById(courseId);

        int result = baseMapper.deleteById(courseId);
        return result > 0;
    }

    @Override
    public List<EduCourse> selectByTeacherId(String id) {
        List<EduCourse> courses = baseMapper.selectList(new LambdaQueryWrapper<EduCourse>()
        .eq(EduCourse::getTeacherId,id)
        .eq(EduCourse::getStatus,CourseConstants.STATUS_NORMAL)
        .orderByDesc(EduCourse::getGmtModified));
        return courses;
    }

    @Override
    public Map<String, Object> getCourseFrontList(Page<EduCourse> pageParam, CourseFrontReq courseQuery) {
        QueryWrapper<EduCourse> queryWrapper = new QueryWrapper<>();
        if (!StringUtils.isEmpty(courseQuery.getSubjectParentId())) {
            queryWrapper.eq("subject_parent_id", courseQuery.getSubjectParentId());
        }

        if (!StringUtils.isEmpty(courseQuery.getSubjectId())) {
            queryWrapper.eq("subject_id", courseQuery.getSubjectId());
        }

        if (!StringUtils.isEmpty(courseQuery.getBuyCountSort())) {
            queryWrapper.orderByDesc("buy_count");
        }

        if (!StringUtils.isEmpty(courseQuery.getGmtCreateSort())) {
            queryWrapper.orderByDesc("gmt_create");
        }

        if (!StringUtils.isEmpty(courseQuery.getPriceSort())) {
            queryWrapper.orderByDesc("price");
        }

        queryWrapper.eq("status", CourseConstants.STATUS_NORMAL);
        baseMapper.selectPage(pageParam, queryWrapper);

        List<EduCourse> records = pageParam.getRecords();
        long current = pageParam.getCurrent();
        long pages = pageParam.getPages();
        long size = pageParam.getSize();
        long total = pageParam.getTotal();
        boolean hasNext = pageParam.hasNext();
        boolean hasPrevious = pageParam.hasPrevious();

        Map<String, Object> map = new HashMap<String, Object>();
        map.put("items", records);
        map.put("current", current);
        map.put("pages", pages);
        map.put("size", size);
        map.put("total", total);
        map.put("hasNext", hasNext);
        map.put("hasPrevious", hasPrevious);

        return map;
    }

    @Override
    public Map<String, Object> getCourseFrontById(String courseId) {
        //查询课程信息和讲师信息
        CourseFrontInfoVo courseWebVo = this.selectInfoWebById(courseId);

        //查询当前课程的章节信息
        List<ChapterVo> chapterVoList = eduChapterService.getChapterVideoByCourseId(courseId);

        HttpServletRequest request = ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();
        String memberId = JwtUtil.getMemberIdByJwtToken(request);
        //判断课程是否被购买
        boolean isBuy = orderService.isBuyCourse(memberId, BusinessEnum.COURSE.getType(),courseId);
        //判断是否收藏
        boolean isCollect = collectService.isCollect(memberId, courseId, BusinessEnum.COURSE.getType());

        //查询推荐课程
        LambdaQueryWrapper<EduCourse> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(EduCourse::getSubjectParentId, courseWebVo.getSubjectLevelOneId());
        wrapper.last("limit 3");
        List<EduCourse> list = this.list(wrapper);
        list.removeIf(item -> item.getId().equals(courseId));
        Map<String, Object> map = new HashMap<>();

        map.put("course", courseWebVo);
        map.put("chapterVoList", chapterVoList);
        map.put("isbuy", isBuy);
        map.put("isCollect", isCollect);
        map.put("recommend", list);

        return map;
    }

    @Override
    public Map<String, Object> getCourseFrontBySectionID(String vid) {
        Map<String, Object> result = new HashMap<>();

        //根据课程获取视频列表
        LambdaQueryWrapper<EduSection> queryListWrapper = new LambdaQueryWrapper<EduSection>()
                .eq(EduSection::getVideoSourceId, vid);
        EduSection section = eduSectionService.getOne(queryListWrapper);

        if (section == null) throw new CommonJsonException(ErrorEnum.E_502);
        queryListWrapper = new LambdaQueryWrapper<EduSection>()
                .eq(EduSection::getCourseId, section.getCourseId());
        List<EduSection> videoList = eduSectionService.list(queryListWrapper);//视频列表

        //获取课程信息
        EduCourse course = this.getById(section.getCourseId());

        if (course == null) throw new CommonJsonException(ErrorEnum.E_90004);
        String teacherId = course.getTeacherId();
        EduTeacher teacher = teacherService.getById(teacherId);

        result.put("videoList", videoList);
        result.put("teacher", teacher);
        result.put("sectionId", section.getId());

        return result;
    }

    /**
     * 前台查询课程详情
     *
     * @param courseId 课程id
     * @return
     */
    @Override
    public CourseFrontInfoVo selectInfoWebById(String courseId) {
        this.updatePageViewCount(courseId);

        return baseMapper.selectInfoWebById(courseId);
    }

    /**
     * 更新浏览量
     *
     * @param id 课程id
     */
    @Override
    public void updatePageViewCount(String id) {
        EduCourse course = baseMapper.selectById(id);
        course.setViewCount(course.getViewCount() + 1);
        baseMapper.updateById(course);
    }

    @Override
    public void updateBuyCount(String id) {
        EduCourse course = baseMapper.selectById(id);
        course.setBuyCount(course.getBuyCount() + 1);
        baseMapper.updateById(course);
    }

    /**
     * 更新课时
     * @param id
     */
    @Override
    public void updateLessonNum(String id, boolean isInsert) {
        EduCourse course = baseMapper.selectById(id);
        if (isInsert) course.setLessonNum(course.getLessonNum() + 1);
        else {
            if (course.getLessonNum() > 0) {
                course.setLessonNum(course.getLessonNum() - 1);
            }
        }
        baseMapper.updateById(course);
    }

    @Override
    public Integer selectCreateCount(String day) {
        return baseMapper.selectCreateCount(day);
    }

    @Override
    public List<EduCourse> searchCourse(String keyword) {
        return baseMapper.searchCourse( keyword);
    }
}
